import base64
import json
import re
import warnings
from urllib.parse import parse_qs, urlparse

import requests
from flask import Blueprint, Flask, request, redirect
from lxml import etree, html

warnings.filterwarnings("ignore")


# 工具函数
def getFirstString(list, idx=0):
    try:
        return list[idx].strip()
    except:
        return ""


# 教务系统会话封装
class JwglManager:
    def __init__(self, session: requests.Session):
        self.session = session

    def get(self, url, params=None):
        return self.session.get(url=url, params=params, verify=False)

    def post(self, url, data=None, json=None, params=None):
        return self.session.post(url=url, data=data, json=json, params=params, verify=False)

    def getRequestText(self, url):
        return self.get(url).text

    def check_login(self):
        try:
            res = self.get("https://byyt.ustb.edu.cn/")
            return res.status_code == 200
        except:
            return False

    def getStudentName(self):
        return getFirstString(etree.HTML(self.getRequestText("https://byyt.ustb.edu.cn/your_jwgl_path"))
                              .xpath("/html/body/div/div[1]/div[2]/div[2]/span[2]/text()"))

    def getStudentId(self):
        text = self.getRequestText("https://byyt.ustb.edu.cn/your_jwgl_path")
        return getFirstString(re.findall("userid = '([0-9a-zA-Z]+)';", text))

    def getSelectedCourseHtml(self, term_id):
        self.post(f'https://byyt.ustb.edu.cn/your_jwgl_path?glyxk=1&jx0502zbid={term_id}')
        return self.post(f'https://byyt.ustb.edu.cn/your_jwgl_path?xsid=&dqjx0502zbid={term_id}&glyxk=1').text

    def getSelectedCourseExcel(self, term_id):
        url = f'https://byyt.ustb.edu.cn/your_jwgl_path?xnxq01id={term_id}&xsxj=1&xsjxl=2&kbjcmsid=16A0B89863824A5ABEECA80B31BB181A'
        return self.post(url).content


# 登录认证流程类
class JwglAutoLoginer:
    def __init__(self):
        self.base_url = "https://byyt.ustb.edu.cn/oauth/login/code"
        self.qrpage_url = "https://sis.ustb.edu.cn/connect/qrpage"
        self.appid = "YW2025006"
        self.return_url = "https://byyt.ustb.edu.cn/oauth/login/code"
        self.sid_regex = re.compile(r'sid = "([a-z0-9]+?)"')
        self.glht_logon_url = "https://byyt.ustb.edu.cn/oauth/login/code?state=null&code="
        self.sso_return_url = "https://sso.ustb.edu.cn/idp/authCenter/authenticateByLck?thirdPartyAuthCode=microQr&lck="

    def get_rand_entityId(self):
        res = requests.get(self.base_url, verify=False)
        parsed_url = urlparse(res.url.replace("#", ""))
        query = parse_qs(parsed_url.query)
        lck = query.get("lck", [None])[0]
        entityId = query.get("entityId", [None])[0]
        return lck, entityId

    def authn_getMic(self, entityId, lck):
        return requests.post("https://sso.ustb.edu.cn/idp/authn/getMicroQr",
                             json={"entityId": entityId, "lck": lck}, verify=False).json()

    def get_sid(self, appid, return_url, rand_token):
        res = requests.get(self.qrpage_url,
                           params={"appid": appid, "return_url": return_url, "rand_token": rand_token, "embed_flag": 1})
        if res.status_code == 200:
            m = self.sid_regex.search(res.text)
            return m.group(1) if m else None
        return None

    def connect_state(self, sid):
        try:
            res = requests.get(f"https://sis.ustb.edu.cn/connect/state?sid={sid}", timeout=2)
            data = res.json()
            if data.get("code") == 1:
                return True, data.get("data")
            return False, data.get("msg", "扫码未完成")
        except:
            return False, "状态检查失败"

    def get_login_code(self, html_text):
        elem = html.fromstring(html_text).xpath('//input[@id="code"]')
        return elem[0].get('value') if elem else ""

    def get_cookie_str(self, session):
        # return '; '.join([f'{k}={v}' for k, v in session.cookies.get_dict().items()])
        return session.cookies.get_dict()